package controllers

import (
	"GoWebBluebell/dao/mysql"
	"GoWebBluebell/logic"
	"GoWebBluebell/models"
	"errors"
	"fmt"

	"github.com/gin-gonic/gin"
	"github.com/go-playground/validator/v10"
	"go.uber.org/zap"
)

func SignUpHandler(c *gin.Context) {
	// 1. 获取参数和参数校验
	p := new(models.ParamSignUp)
	err := c.ShouldBindJSON(p) //gin框架从请求里把数据绑定到结构体里(只会验证类型和格式JSON 不判断数量和其他)
	if err != nil {
		//请求参数有误, 直接返回响应
		zap.L().Error("SignUp with invalid param", zap.Error(err))
		errs, ok := err.(validator.ValidationErrors) //判断是否为validator类型的错误
		if !ok {
			ResponseError(c, CodeInvalidParam)
			return
		}
		errData := removeTopStruct(errs.Translate(trans))
		ResponseErrorWithMsg(c, CodeInvalidParam, errData) //翻译错误 trans是翻译器
		return

	}
	//fmt.Println(p)
	// 2. 业务处理(放入logic层)
	if err = logic.SignUp(p); err != nil {
		zap.L().Error("logic.SighUp failed", zap.Error(err))
		if errors.Is(err, mysql.ErrorUserExist) { //判断错误是否为
			ResponseError(c, CodeUserExist)
			return
		}
		ResponseError(c, CodeServerBusy)
		return
	}
	// 3. 返回响应
	ResponseSuccess(c, nil)
}

func LoginHandler(c *gin.Context) {
	// 1. 获取参数和参数校验
	p := new(models.ParamLogin)
	err := c.ShouldBindJSON(p) //gin框架从请求里把数据绑定到结构体里(只会验证类型和格式JSON 不判断数量和其他)
	if err != nil {
		//请求参数有误, 直接返回响应
		zap.L().Error("Login with invalid param", zap.Error(err))
		errs, ok := err.(validator.ValidationErrors) //判断是否为validator类型的错误
		if !ok {
			ResponseError(c, CodeInvalidParam)
			return
		}
		ResponseErrorWithMsg(c, CodeInvalidParam, removeTopStruct(errs.Translate(trans))) //翻译错误 trans是翻译器
		return
	}
	//fmt.Println(p)
	// 2. 业务处理(放入logic层)
	user, err := logic.Login(p)
	if err != nil {
		zap.L().Error("logic.Login failed", zap.Error(err))
		ResponseError(c, CodeInvaildPassword)
		return

	}
	// 3. 返回响应
	ResponseSuccess(c, gin.H{
		"user_id":   fmt.Sprintf("%d", user.UserID), //将int64转为string防止json解析溢出
		"user_name": user.Username,
		"token":     user.Token,
	})
}
